<template>
  <!-- 申报策略 -->
  <div class="filterContent">
    <a-form :model="filterForm" layout="inline">
      <a-form-item label="模式">
        <a-select
          ref="select"
          v-model:value="filterForm.mode"
          class="formInput"
          placeholder="请选择模式"
          show-search
          optionFilterProp="label"
          @change="changeProv"
          allowClear
        >
          <a-select-option :value="0">削峰</a-select-option>
          <a-select-option :value="1">填谷</a-select-option>
        </a-select>
      </a-form-item>
      <a-form-item label="执行日期">
        <a-range-picker
          v-model:value="filterForm.date"
          value-format="YYYY-MM-DD HH:mm"
          format="YYYY-MM-DD HH:mm"
          allowClear
          separator="~"
          show-time
        />
      </a-form-item>
      <a-button type="primary" class="filterBtn" @click="getDeclareList"
        >查询</a-button
      >
      <a-button
        type="primary"
        class="filterBtn greenBtn"
        @click="handleBaseImport"
        v-hasPermission="'declareBaseImport'"
        >基线导入</a-button
      >
      <a-button
        type="primary"
        class="filterBtn greenBtn"
        @click="handleElecImport"
        v-hasPermission="'declareElecImport'"
        >用户电量导入</a-button
      >
      <a-button v-hasPermission="'declareAdd'" type="primary" class="yellowBtn" @click="handleAdd"
        >新增</a-button
      >
    </a-form>
  </div>
  <div class="priceContent">
    <div class="ruleContent">
      <div class="title">申报策略记录</div>
      <div class="ruleList">
        <a-spin :spinning="loading" style="width: 100%; height: 200px">
          <div
            v-for="(item, index) in ruleList"
            :class="['rule', item.selected ? 'active' : '']"
            :key="index"
            @click="handleSelect(item, index)"
          >
            <div :class="['ruleType', item.mode ? 'tiangu' : 'xuefeng']" />
            <div class="ruleName">{{ item.strategyName }}</div>
            <div
              :class="['statusIcon', item.mode ? 'tianguIcon' : 'xuefengIcon']"
            >
              <span />
              {{ item.mode ? "填谷" : "削峰" }}
            </div>
            <div class="ruleTime">
              <span>执行日期：{{ item.executionDate?.split(" ")[0] }}</span>
              <span>户号：{{ item?.customerNumber || "--" }}</span>
            </div>
            <div class="ruleTime">
              企业名称：{{ item?.companyName || "--" }}
            </div>
            <div class="ruleTime">
              户号名称：{{ item?.customerName || "--" }}
            </div>
            <div class="ruleDate">
              <span class="dateLabel">执行时段：</span
              ><span class="dateValue"
                ><span
                  v-for="(timeItem, timeIndex) in item.executionPeriod"
                  :key="timeIndex"
                  >{{ timeItem
                  }}<span
                    v-if="
                      timeIndex % 2 == 0 &&
                      timeIndex != item.executionPeriod.length - 1
                    "
                    >、</span
                  ></span
                ></span
              >
            </div>
          </div>
          <a-empty
            v-if="!ruleList.length"
            style="opacity: 0.5; margin-top: 50px"
          />
        </a-spin>
      </div>
    </div>
    <div class="dateContent">
      <div class="title">申报策略详情</div>
      <a-spin :spinning="chartLoading" style="width: 100%; height: 200px">
        <div class="calendar">
          <div
            id="demandResponse"
            class="chartContainer"
            v-if="!!Object.keys(chartData).length"
          />
          <a-empty
            v-if="!Object.keys(chartData).length"
            style="opacity: 0.5; margin-top: 50px"
          />
          <div class="tableData">
            <a-table
              :dataSource="tableData"
              :columns="columns"
              size="small"
              @resizeColumn="handleResizeColumn"
              :pagination="false"
            >
              <template #bodyCell="{ column, record, index }">
                <template v-if="column.key === 'index'">
                  {{ index + 1 }}
                </template>
                <template v-if="column.key === 'applyDate'">
                  <span v-if="!record.isEdit" class="suggest">{{
                    `${record?.applyDate[0]}~${record?.applyDate[1]}`
                  }}</span>
                  <a-time-range-picker
                    v-else
                    v-model:value="record.applyDate"
                    value-format="HH:mm"
                    format="HH:mm"
                    separator="~"
                    showTime
                  />
                </template>
                <template v-if="column.key === 'reactCommand'">
                  <span v-if="!record.isEdit" class="suggest">{{
                    record.reactCommand
                  }}</span>
                  <a-input-number
                    v-else
                    v-model:value="record.reactCommand"
                    :controls="false"
                  />
                </template>
                <template v-if="column.key === 'handle'">
                  <a-button
                    v-if="!record.isEdit"
                    type="link"
                    @click="handleEdit(index)"
                    v-hasPermission="'declareEdit'"
                    >编辑</a-button
                  >
                  <a-button v-else type="link" @click="handleSave(index)"
                    >保存</a-button
                  >
                </template>
              </template>
            </a-table>
          </div>
        </div>
      </a-spin>
    </div>
  </div>
  <!-- 新增申报策略 -->
  <AddRule
    :addRuleVisible="addRuleVisible"
    :rowData="rowData"
    @update:addRuleVisible="(val) => (addRuleVisible = val)"
    @getDeclareList="getDeclareList"
  />

  <!-- 基线导入 -->
  <ImportBase
    :importBaseVisible="importBaseVisible"
    @update:importBaseVisible="(val) => (importBaseVisible = val)"
  />

  <!-- 用户电量导入 -->
  <ImportElec
    :importElecVisible="importElecVisible"
    @update:importElecVisible="(val) => (importElecVisible = val)"
  />
</template>
<script setup>

import AddRule from "./components/addRule.vue";
import ImportBase from "./components/ImportBase.vue";
import ImportElec from "./components/ImportElec.vue";
import { chartOption } from "./chartOption";
import * as echarts from "echarts";

import { cloneDeep, pickBy } from "lodash-es";
const $api = inject("$api");
const addRuleVisible = ref(false);
const importBaseVisible = ref(false);
const importElecVisible = ref(false);
const filterForm = ref({
  mode: null,
  date: null,
});
const handleAdd = () => {
  addRuleVisible.value = true;
};
const ruleList = ref([]);
const loading = ref(false);
const tableData = ref([]);
function handleResizeColumn(w, col) {
  col.width = w;
}
const columns = ref([
  {
    title: "序号",
    dataIndex: "index",
    key: "index",
    width: 60,
    align: "center",
    ellipsis: true,
    fixed: "left",
  },
  {
    title: "申报时间",
    dataIndex: "applyDate",
    key: "applyDate",
    align: "center",
  },
  {
    title: "响应容量（kWh）",
    dataIndex: "reactCommand",
    key: "reactCommand",
    align: "center",
  },
  {
    title: "操作",
    dataIndex: "handle",
    key: "handle",
    width: 120,
    align: "center",
  },
]);
const getDeclareList = async () => {
  const params = {
    mode: filterForm.value.mode,
    runStartDate: filterForm.value.date?.[0]
      ? filterForm.value.date[0] + ":00"
      : "",
    runEndDate: filterForm.value.date?.[1]
      ? filterForm.value.date[1] + ":00"
      : "",
    current: 1,
    size: 9999,
  };
  loading.value = true;
  const res = await $api.applyStrategyList(pickBy(params));
  loading.value = false;
  if (res && res.code === 0) {
    ruleList.value = res.data.records.map((item) => {
      return {
        ...item,
        selected: false,
      };
    });
  }
};
const rowData = ref({});
const executionPeriod = ref([]);
const initExecutionPeriod = () => {
  // 初始化申报时间
  executionPeriod.value = [];
  tableData.value.forEach((item, index) => {
    executionPeriod.value[index] = `${item.applyDate[0]}~${item.applyDate[1]}`;
  });
};
const handleSelect = (item, index) => {
  for (const item of ruleList.value) {
    item.selected = false;
  }
  ruleList.value[index].selected = true;
  getApplyStrategyDetails(item);
};
const chartData = ref({});
const getApplyStrategyDetails = async (item) => {
  chartLoading.value = true;
  const res = await $api.applyStrategyDetails(item.id);
  chartLoading.value = false;
  if (res?.code === 0 && Object.keys(res.data).length) {
    chartData.value = res.data;
    tableData.value = res.data.applyList.map((item) => {
      return {
        ...item,
        isEdit: false,
        applyDate: item.applyDate.split("~"),
      };
    });
    initExecutionPeriod();
    await nextTick();
    initChartData();
  } else {
    chartData.value = {};
  }
};
const declareChart = ref({});
const chartLoading = ref(false);
const initChartData = async () => {
  declareChart.value = cloneDeep(chartOption);
  declareChart.value.xAxis.data = chartData.value?.baseCurve?.map(
    (item) => item.date
  );
  declareChart.value.series[0].data = chartData.value?.baseCurve?.map(
    (item) => item.value
  );
  declareChart.value.series[1].data = chartData.value?.costCurve?.map(
    (item) => item.value
  );
  // 获取执行周期的时间段数据的反应曲线
  const reactCurve = [];
  // 遍历每个时间范围
  for (const time of executionPeriod.value) {
    const [startHour, endHour] = time.split("~").map((t) => t.split(":")[0]);
    for (const item of chartData.value?.reactCurve || []) {
      const hour = item.date.split(":")[0];
      // 只保留在时间段内的数据
      if ((hour === startHour || hour > startHour) && hour <= endHour) {
        reactCurve.push(item);
      }
    }
  }
  // 根据xAxis获取所有小时时间数组，并将数据集合转为查找表
  const allHours = new Set(
    declareChart.value.xAxis.data
      ?.map((date) => {
        return { date, value: null };
      })
      .map((item) => item.date)
  );
  // 从 reactCurve 中提取已有的小时数据
  const existingHours = new Set(reactCurve.map((item) => item.date));
  // 遍历 allHours 数组，补充缺失的点
  for (const date of allHours) {
    if (!existingHours.has(date)) {
      reactCurve.push({ date, value: null });
    }
  }
  // 对 reactCurve 按照时间排序
  reactCurve.sort((a, b) => a.date.localeCompare(b.date));
  // 更新图表系列数据
  declareChart.value.series[2].data = reactCurve
    .map((item) => item.value)
    .slice(0, declareChart.value.xAxis.data?.length);

  const chartEl = document.getElementById("demandResponse");
  if (chartEl) {
    const chartInstance = echarts.init(chartEl);
    chartInstance.resize();
    chartInstance.clear();
    chartInstance.setOption(declareChart.value);
  }
};
const handleEdit = (index) => {
  tableData.value[index].isEdit = true;
};
const handleSave = async (index) => {
  const params = {
    id: tableData.value[index].id,
    strategyId: ruleList.value.find((item) => item.selected).id,
    applyDate: `${tableData.value[index].applyDate[0]}~${tableData.value[index].applyDate[1]}`,
    reactCommand: tableData.value[index].reactCommand,
  };
  const res = await $api.setStrategy(params);
  tableData.value[index].isEdit = false;
  if (res && res.code === 0) {
    message.success("编辑成功");
    // 编辑后，更新的执行时间同步更新到图表上
    initExecutionPeriod();
    initChartData();
  }
};
const handleBaseImport = () => {
  importBaseVisible.value = true;
};
const handleElecImport = () => {
  importElecVisible.value = true;
};
onMounted(() => {
  getDeclareList();
});
</script>

<style lang="less" scoped>
.formInput {
  width: 155px;
}
.priceContent {
  display: table;
}
.ruleContent,
.dateContent {
  border-radius: 4px;
  background-color: #141414;
  border: 1px solid #666;
  border-radius: 4px;
  .title {
    height: 50px;
    line-height: 50px;
    border-bottom: 1px solid #666;
    font-size: 14px;
    padding: 0 20px;
    position: relative;
  }
  .addRule {
    position: absolute;
    right: 20px;
    top: 10px;
  }
}
.ruleContent {
  width: 450px;
  margin-right: 20px;
  height: 816px;
}
.dateContent {
  width: 100%;
  vertical-align: top;

  display: table-cell;
}
.ruleList {
  padding: 20px 15px;
  height: 750px;
  overflow-y: scroll;
}
.rule {
  border: 1px solid #666;
  border-radius: 4px;
  padding: 10px 20px 10px 20px;
  margin-bottom: 20px;
  position: relative;
  cursor: pointer;
  &:last-child {
    margin-bottom: 0;
  }
  .ruleType {
    width: 3px;
    height: calc(100% - 20px);
    left: 9px;
    position: absolute;
  }
  .ruleName {
    font-size: 14px;
    margin-bottom: 10px;
  }
  .ruleDate {
    font-size: 12px;
  }
  .ruleTime {
    font-size: 12px;
    margin-bottom: 5px;
    span {
      display: inline-block;
      &:first-child {
        margin-right: 10px;
      }
    }
  }
  .dateLabel {
    display: inline-block;
    width: 60px;
    position: relative;
    top: 2px;
  }
  .dateValue {
    display: inline-block;
    width: calc(100% - 60px);
    vertical-align: text-top;
    line-height: 1.5;
  }
}
.xuefeng {
  background: #1890ff;
}
.xuefengIcon {
  color: #1890ff;
  span {
    display: inline-block;
    background: url("@/assets/xuefeng.png") no-repeat center center;
    background-size: contain;
    width: 20px;
    height: 20px;
    vertical-align: bottom;
  }
}
.tianguIcon {
  color: green;
  span {
    display: inline-block;
    background: url("@/assets/tiangu.png") no-repeat center center;
    background-size: contain;
    width: 20px;
    height: 20px;
    vertical-align: bottom;
  }
}
.tiangu {
  background: green;
}
.filterBtn {
  margin-right: 20px;
}
.active {
  border: 1px solid red;
  background-color: rgba(255, 0, 0, 0.06);
}
.statusIcon {
  position: absolute;
  right: 8px;
  top: 10px;
  font-size: 12px;
}
.chartContainer {
  width: 100%;
  height: 400px;
}
.tableData {
  padding: 0 20px;
  margin-top: 20px;
}
.filterContent {
  .ant-btn {
    margin-bottom: 20px;
  }
}
</style>
